package com.yhb.channel.utils;
import com.yhb.channel.exception.PayChannelException;
import com.yhb.channel.provider.IUtilProvider;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.extern.log4j.Log4j;
import lombok.var;
import org.jetbrains.annotations.NotNull;

import java.lang.reflect.InvocationTargetException;

@Log4j
@Data
@Builder
@AllArgsConstructor
public class ChannelLogger {
    private String CHANNEL_NAME;
    private Class<? extends PayChannelException> exceptionCls;
    private IUtilProvider iUtilProvider;

//    public ChannelLogger(String CHANNEL_NAME, Class<? extends PayChannelException> exceptionCls) {
//        this.CHANNEL_NAME = CHANNEL_NAME;
//        this.exceptionCls = exceptionCls;
//    }

    public void info(String msg) {
        log.info(CHANNEL_NAME + "通道:" + msg);
    }

    public void info(@NotNull String... messages) {
        log.info(CHANNEL_NAME + "通道: \n");
        for (String msg : messages) {
            log.info(msg);
        }
    }

    public void fail(long code, String msg) {
        fail(code, msg, null);
    }

    public void fail(long code, String msg, Throwable e) {
        fail(code, msg, e, null);
    }

    public void fail(long code, String msg, Throwable e, String extendInfo) {
        log.info(CHANNEL_NAME + "通道异常:" + msg, e);
        RuntimeException payException = null;
        try {
            payException = exceptionCls.getConstructor(Long.class, String.class, Throwable.class).newInstance(code, msg, e);
        } catch (InstantiationException | IllegalAccessException
                | InvocationTargetException | NoSuchMethodException ex) {
            log.error(ex);
            var exe = new PayChannelException(code, msg, e);
            exe.setExtendInfo(extendInfo);
            throw exe; // 反射失败就抛一个通用的
        }
        throw payException;
    }

    public void errorInfo(String info) {
        log.error(CHANNEL_NAME + "通道异常:" + info);
        log.error(info);
    }

    public void errorInfo(String info, Throwable e) {
        log.error(CHANNEL_NAME + "通道异常:" + info , e);
        log.error(info, e);
    }

    public void logRequest(String method, String requestId, String req) {
        String flow = method + "::::" + requestId + "\n请求包 ==> " + req;
        info(flow);
        saveRequestFlow(flow);
    }

    public void logResponse(String method, String requestId, String res) {
        String flow = method + "::::" + requestId + "\n回包 ==> " + res;
        info(flow);
        saveRequestFlow(flow);
    }

    public void logAsyncResponse(String action, String requestId, String callbackContent) {
        String flow = action + "::::" + requestId + "\n回调内容 =>" + callbackContent;
        info(flow);
        saveRequestFlow(flow);
    }

    public void saveRequestFlow(String flow) {
        if (iUtilProvider == null) {
            return;
        }
        iUtilProvider.savePayChannelFlow(CHANNEL_NAME + "---", flow);
    }
}
